import { any } from "../../../core/logic";
import { Engine } from "../../../Engine";
import { Pass } from "../Pass";
import { Effect, EffectType } from "./Effect";
import { taa_vert } from "./shaders/taa_vert";
import { taa_frag } from "./shaders/taa_frag";
import { TAAComputer } from "../compute/TAAComputer";
/**
 * TAA抗锯齿。
 * @class
 * @memberof w.effects
 */
class TAA extends Effect {
  /**
   * @constructor
   * @param {*} opts
   * @param {Boolean} opts.blendColor 【可选,缺省:true】是否混合。
   * @param {Number} opts.blendFactor 【可选,缺省:0.3】混合因子。
   * @example
   * let taa=new w.effects.TAA({blendFactor:1.0,blendColor:true});
   */
  constructor(opts = {}) {
    super(opts);
    this.type = EffectType.TAA;
    this.sampler = Engine.instance.device.createSampler({
      magFilter: "linear", //nearest linear
      minFilter: "linear",
    });
    this.taaComputer = new TAAComputer(opts);
    this.addCompute(this.taaComputer);
    this.initPipeLine();
    this.blendColor = any(opts.blendColor, true);
    this.mouseFlag = false;
    this.listenMouse();
  }
  set blendColor(v) {
    this.taaComputer.blendColor = v;
    return this;
  }
  get blendColor() {
    return this._blendColor;
  }
  listenMouse() {
    const canvas = Engine.instance.canvas;
    canvas.addEventListener("mousedown", event => {
      this.mouseFlag = true;
    });
    canvas.addEventListener("click", event => {
      this.mouseFlag = true;
    });
    canvas.addEventListener("wheel", event => {
      this.mouseFlag = true;
    });
    // 鼠标移动
    // canvas.addEventListener("mousemove", event => {
    //   this.mouseFlag = true;
    // });
  }
  initPipeLine() {
    this.pipeLine = Engine.instance.device.createRenderPipeline({
      label: "gtao Pipline",
      layout: `auto`,
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: taa_vert,
        }),
        entryPoint: "main",
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: taa_frag,
        }),
        entryPoint: "main",
        targets: [
          {
            format: Engine.instance.format,
          },
        ],
      },
      primitive: {
        topology: "triangle-list",
        cullMode: "back",
        frontFace: "ccw",
      },
    });
  }
  initBindGroup() {
    const taaTexture = this.taaComputer.preColorTex;
    if (this.bindGroup && this.bindGroup.id != taaTexture.id) {
      this.bindGroup = null;
    }
    if (!this.bindGroup) {
      this.bindGroup = Engine.instance.device.createBindGroup({
        label: "Texture Group with Texture/Sampler",
        layout: this.pipeLine.getBindGroupLayout(0),
        entries: [
          {
            binding: 0,
            resource: this.sampler,
          },
          {
            binding: 1,
            resource: taaTexture.view,
          },
        ],
      });
    }
    this.bindGroup.id = taaTexture.id;
    return this.bindGroup;
  }
  onRender(commandEncoder) {
    //执行帧渲染
    const pass = super.onRender(commandEncoder);
    const renderPass = commandEncoder.beginRenderPass(pass);
    renderPass.setPipeline(this.pipeLine);
    let bindGroup = this.initBindGroup();
    renderPass.setBindGroup(0, bindGroup);
    renderPass.draw(3);
    renderPass.end();
    if (!this.mouseFlag) {
      this.onRender1(commandEncoder)
    }
  }
  onRender1(commandEncoder) {
    //执行帧渲染
    for (let index = 0; index < 10; index++) {
      const pass = super.onRender(commandEncoder);
      const renderPass = commandEncoder.beginRenderPass(pass);
      renderPass.setPipeline(this.pipeLine);
      let bindGroup = this.initBindGroup();
      renderPass.setBindGroup(0, bindGroup);
      renderPass.draw(3);
      renderPass.end();
    }
  }
  getDescript() {
    if (this._descript) {
      if (
        this._descript.size[0] !== Engine.instance.size[0] ||
        this._descript.size[1] !== Engine.instance.size[1]
      ) {
        this._descript = null;
      } else {
        this._descript.colorAttachments[0].view = Pass.instance().writeAttach.view;
      }
    }
    if (!this._descript) {
      this._descript = {
        colorAttachments: [
          {
            view: Pass.instance().writeAttach.view,
            loadOp: "clear",
            clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
            storeOp: "store",
          },
        ],
      };
      this._descript.size = Engine.instance.size;
    }
    return this._descript;
  }
}
export { TAA };
